package com.erpanderp.wam.adm.view;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;

import com.erpanderp.wam.adm.model.entity.Module;
import com.erpanderp.wam.adm.model.entity.Resource;
import com.erpanderp.wam.adm.model.entity.Role;
import com.erpanderp.wam.adm.model.entity.RoleService;
import com.erpanderp.wam.adm.model.entity.RoleServiceGroup;
import com.erpanderp.wam.adm.model.entity.Service;
import com.erpanderp.wam.adm.model.entity.ServiceGroup;
import com.erpanderp.wam.adm.model.service.RoleDAO;
import com.erpanderp.wam.adm.model.service.RoleServiceDAO;
import com.erpanderp.wam.adm.model.service.RoleServicegroupDAO;
import com.erpanderp.wam.adm.model.service.ServiceDAO;
import com.erpanderp.wam.adm.model.service.ServiceGroupDAO;
import com.erpanderp.wam.usm.model.entity.leave.LeaveType;
import com.erpanderp.wam.usm.model.service.leave.LeaveTypeDAO;
import com.erpanderp.wam.usm.model.service.leave.LeaveTypeRoleDAO;
import com.erpanderp.wam.util.CommonLookup;

@ManagedBean
@ViewScoped
public class RolesBean implements Serializable {
	private Map<String, String> roleTypes = CommonLookup.getRoleTypes();
	private static final long serialVersionUID = 1L;
	private Map<String, Long> rolesMap = new HashMap<String, Long>();
	private Map<String, Long> servicesMap = new HashMap<String, Long>();

	RoleDAO roleDAO = new RoleDAO();
	ServiceDAO serviceDAO = new ServiceDAO();
	ServiceGroupDAO serviceGroupDAO = new ServiceGroupDAO();
	RoleServiceDAO roleServiceDAO = new RoleServiceDAO();
	RoleServicegroupDAO roleServiceGroupDAO = new RoleServicegroupDAO();

	private List<Role> roles = new ArrayList<Role>();	
	private List<Service> services = new ArrayList<Service>();
	private List<ServiceGroup> serviceGroups = new ArrayList<ServiceGroup>();
	private List<Service> assignedServices = new ArrayList<Service>();
	private List<ServiceGroup> assignedServiceGroups = new ArrayList<ServiceGroup>();
	private List<LeaveType> leavesTypes = new ArrayList<LeaveType>();
	private LeaveTypeRoleDAO leaveTypeRoleDAO = new LeaveTypeRoleDAO();
	private LeaveTypeDAO leaveTypeDAO = new LeaveTypeDAO();
	private List<LeaveType> assignedLeaveTypes = new ArrayList<LeaveType>();

	private Long selectedRoleId;
	private Role selectedRole;

	private boolean detailsForRole;

	public RolesBean() {
		setDetailsForRole(false);
		roles = roleDAO.getAllRoles();
		for (Role role : roles) {
			rolesMap.put(role.getRole(), role.getRoleId());
		}
	}

	public void roleChangeListener(AjaxBehaviorEvent e) {

		assignedServiceGroups.clear();
		assignedServices.clear();
		services = serviceDAO.getAllServices();
		serviceGroups = serviceGroupDAO.getAllServiceGroups();
		leavesTypes = leaveTypeDAO.getLeaveTypes();
		
		if (selectedRoleId == null || selectedRoleId == 0) {
			setDetailsForRole(false);
		} else {
			
			selectedRole = roleDAO.getRoleByRoleID(selectedRoleId);
			
			if (selectedRole.getDescription() == null
					|| selectedRole.getDescription().equals("")) {
				selectedRole.setDescription("Enter Description");
			}

			assignedServices = roleDAO.getServicesByRoleId(selectedRoleId);
			assignedServiceGroups = roleDAO.getServiceGroupsByRoleId(selectedRoleId);
			assignedLeaveTypes = roleDAO.getLeaveTypesByRoleId(selectedRoleId);
			for(Service service : services){
				if(assignedServices.contains(service)){
					service.setAssigned(true);
					service.setChecked(true);
				}
			}
			for(ServiceGroup serviceGroup : serviceGroups){
				if(assignedServiceGroups.contains(serviceGroup)){
					serviceGroup.setAssigned(true);
					serviceGroup.setChecked(true);
				}
			}
			for(LeaveType leaveType : leavesTypes){
				if(assignedLeaveTypes.contains(leaveType)){
					leaveType.setAssigned(true);
					leaveType.setChecked(true);
				}
			}
			setDetailsForRole(true);
		}

	}

	public String updateRoleAction() {	
		Date now = new Date();
		assignedServiceGroups.clear();
		assignedServices.clear();
		
		List<RoleServiceGroup> toBeDeletedRoleServiceGroups = new ArrayList<RoleServiceGroup>();
		List<RoleService> toBeDeletedRoleServices = new ArrayList<RoleService>();
		
		for(ServiceGroup serviceGroup : serviceGroups){			
			if(!serviceGroup.isAssigned() && serviceGroup.isChecked()){
				assignedServiceGroups.add(serviceGroup);
				RoleServiceGroup roleServiceGroup = new RoleServiceGroup();
				roleServiceGroup.setCreateDate(now);
				roleServiceGroup.setCreatedBy(CommonLookup.CREATEDBY_DEVELOPER_TEXT);
				roleServiceGroup.setRole(selectedRole);
				roleServiceGroup.setServiceGroup(serviceGroup);
				roleServiceGroup.setStatus(CommonLookup.STATUS_ACTIVE);
				selectedRole.getRoleServiceGroups().add(roleServiceGroup);
				System.out.println("SERVICE GROUP ADDED");
			}
			if(serviceGroup.isAssigned() && !serviceGroup.isChecked()){
				toBeDeletedRoleServiceGroups.add(roleServiceGroupDAO.getRoleServicegroup(selectedRole.getRoleId(), serviceGroup.getServiceGroupId()));
			}
		}
		
		System.out.println(selectedRole.getRoleServiceGroups().size());
		for(Service service : services){			
			if(!service.isAssigned() && service.isChecked()){
				assignedServices.add(service);
				RoleService roleService = new RoleService();
				roleService.setCreateDate(now);
				roleService.setCreatedBy(CommonLookup.CREATEDBY_DEVELOPER_TEXT);
				roleService.setRole(selectedRole);
				roleService.setService(service);
				roleService.setStatus(CommonLookup.STATUS_ACTIVE);
				selectedRole.getRoleServices().add(roleService);
				System.out.println("SERVICE ADDED");
			}
			if(service.isAssigned() && !service.isChecked()){
				toBeDeletedRoleServices.add(roleServiceDAO.getRoleService(selectedRole.getRoleId(), service.getServiceId()));
			}
		}	
		
		roleDAO.updateRole(selectedRole);
		roleServiceGroupDAO.deleteRoleServiceGroups(toBeDeletedRoleServiceGroups);
		roleServiceDAO.deleteRoleServices(toBeDeletedRoleServices);
		
		return null;
	}

	// GETTERS AND SETTERS
	public Map<String, Long> getRolesMap() {
		return rolesMap;
	}

	public void setRolesMap(Map<String, Long> rolesMap) {
		this.rolesMap = rolesMap;
	}

	public RoleDAO getRoleDAO() {
		return roleDAO;
	}

	public void setRoleDAO(RoleDAO roleDAO) {
		this.roleDAO = roleDAO;
	}

	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	public Long getSelectedRoleId() {
		return selectedRoleId;
	}

	public void setSelectedRoleId(Long selectedRoleId) {
		this.selectedRoleId = selectedRoleId;
	}

	public Role getSelectedRole() {
		return selectedRole;
	}

	public void setSelectedRole(Role selectedRole) {
		this.selectedRole = selectedRole;
	}

	public boolean isDetailsForRole() {
		return detailsForRole;
	}

	public void setDetailsForRole(boolean detailsForRole) {
		this.detailsForRole = detailsForRole;
	}

	public Map<String, Long> getServicesMap() {
		return servicesMap;
	}

	public void setServicesMap(Map<String, Long> servicesMap) {
		this.servicesMap = servicesMap;
	}

	public Map<String, String> getRoleTypes() {
		return roleTypes;
	}

	public void setRoleTypes(Map<String, String> roleTypes) {
		this.roleTypes = roleTypes;
	}

	public List<Service> getServices() {
		return services;
	}

	public void setServices(List<Service> services) {
		this.services = services;
	}

	public List<ServiceGroup> getServiceGroups() {
		return serviceGroups;
	}

	public void setServiceGroups(List<ServiceGroup> serviceGroups) {
		this.serviceGroups = serviceGroups;
	}

	public List<Service> getAssignedServices() {
		return assignedServices;
	}

	public void setAssignedServices(List<Service> assignedServices) {
		this.assignedServices = assignedServices;
	}

	public List<ServiceGroup> getAssignedServiceGroups() {
		return assignedServiceGroups;
	}

	public void setAssignedServiceGroups(List<ServiceGroup> assignedServiceGroups) {
		this.assignedServiceGroups = assignedServiceGroups;
	}

	public List<LeaveType> getLeavesTypes() {
		return leavesTypes;
	}

	public void setLeavesTypes(List<LeaveType> leavesTypes) {
		this.leavesTypes = leavesTypes;
	}

	public List<LeaveType> getAssignedLeaveTypes() {
		return assignedLeaveTypes;
	}

	public void setAssignedLeaveTypes(List<LeaveType> assignedLeaveTypes) {
		this.assignedLeaveTypes = assignedLeaveTypes;
	}

}
